﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit.RevitExtension;
using HYRevitCode.RevitObjectCompareUtility;
using YJKRGeometry;
using TopologySearch.LoopSearch;

namespace TopologySearch
{
	public class StructureLoopSearcher
	{
		public StructureLoopSearcher(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
			this.m_Doc = cmdData.Application.ActiveUIDocument.Document;
			this.m_OldEps = XYZComparer._eps;
		}

		public StructureLoopSearcher(ExternalCommandData cmdData, double dEps)
		{
			this.m_Revit = cmdData;
			this.m_Doc = cmdData.Application.ActiveUIDocument.Document;
			this.m_OldEps = XYZComparer._eps;
			XYZComparer._eps = dEps;
		}

		public StructureLoopSearcher(Autodesk.Revit.DB.Document doc)
		{
			this.m_Doc = doc;
			this.m_OldEps = XYZComparer._eps;
		}

		public StructureLoopSearcher(Autodesk.Revit.DB.Document doc, double dEps)
		{
			this.m_Doc = doc;
			this.m_OldEps = XYZComparer._eps;
			XYZComparer._eps = dEps;
		}

		~StructureLoopSearcher()
		{
			XYZComparer._eps = this.m_OldEps;
		}

		public List<List<Curve>> GetFullFloorEdgeLoops(List<Pole2D> poleList, StructureLoopSearcher.SearchEdgeLocation edgeLocation = StructureLoopSearcher.SearchEdgeLocation.SEL_Outside)
		{
			List<List<ElementId>> list = new List<List<ElementId>>();
			List<List<Curve>> result = new List<List<Curve>>();
			this.GetFullFloorEdgeLoops(poleList, true, edgeLocation, ref list, ref result);
			return result;
		}

		public List<List<Curve>> GetFullFloorEdgeLoops(List<Pole2D> poleList, ref List<List<ElementId>> edgeLoopsElementIds, StructureLoopSearcher.SearchEdgeLocation edgeLocation = StructureLoopSearcher.SearchEdgeLocation.SEL_Outside)
		{
			List<List<Curve>> result = new List<List<Curve>>();
			this.GetFullFloorEdgeLoops(poleList, true, edgeLocation, ref edgeLoopsElementIds, ref result);
			return result;
		}

		public List<List<Curve>> GetFullFloorInEdgeLoops(List<Pole2D> poleList, ref List<List<ElementId>> edgeLoopsElementIds, StructureLoopSearcher.SearchEdgeLocation edgeLocation = StructureLoopSearcher.SearchEdgeLocation.SEL_Inside)
		{
			List<List<Curve>> result = new List<List<Curve>>();
			this.GetFullFloorEdgeLoops(poleList, true, edgeLocation, ref edgeLoopsElementIds, ref result);
			return result;
		}

		public bool GetBoundaryPoles(List<Pole2D> poleList, StructureLoopSearcher.SearchEdgeLocation edgeLocation, ref List<List<Pole2D>> poleLoops)
		{
			return this.GetFullFloorEdgeLoops(poleList, false, edgeLocation, ref poleLoops);
		}

		public List<List<Curve>> GetFullFloorEdgeLoops(List<Pole2D> poleList, bool mergeEdge, ref List<List<ElementId>> edgeLoopsElementIds, StructureLoopSearcher.SearchEdgeLocation edgeLocation = StructureLoopSearcher.SearchEdgeLocation.SEL_Outside)
		{
			List<List<Curve>> result = new List<List<Curve>>();
			this.GetFullFloorEdgeLoops(poleList, mergeEdge, edgeLocation, ref edgeLoopsElementIds, ref result);
			return result;
		}

		public List<List<Curve>> GetFullFloorEdgeLoops(List<Pole2D> poleList, ref List<Curve> internalCurves, bool bisNeedAddCurve = false, bool bisNeedMerge = true, StructureLoopSearcher.SearchEdgeLocation edgeLocation = StructureLoopSearcher.SearchEdgeLocation.SEL_Outside)
		{
			List<List<Curve>> list = new List<List<Curve>>();
			List<List<Curve>> result;
			try
			{
				if (poleList.Count == 0)
				{
					result = list;
				}
				else
				{
					List<Pole2D> list2 = this.SegmentPoleList(poleList);
					List<Pole2D> poleList2 = this.FilterOverlapPoleList(list2);
					List<Node2D> theNodes = new List<Node2D>();
					this.InitData(poleList2, Node2D.SearchType._Anticlockwise, ref theNodes);
					if (bisNeedMerge)
					{
						this.MergeEdge(ref theNodes);
					}
					List<List<Pole2D>> outPoleList = new List<List<Pole2D>>();
					if (!this.SearchOuterBoundary(theNodes, ref outPoleList))
					{
						result = list;
					}
					else
					{
						List<List<Pole2D>> list3 = new List<List<Pole2D>>();
						this.FormatPoleLoops(outPoleList, ref list3);
						this.GetLoopCurves(list3, edgeLocation, ref list, bisNeedAddCurve);
						this.GetInternalCurves(list3, list2, list, ref internalCurves);
						result = list;
					}
				}
			}
			catch (Exception)
			{
				result = list;
			}
			return result;
		}

		public List<List<Curve>> GetCellsEdgeLoops(List<Pole2D> poleList, bool bMergeEdge = true)
		{
			List<List<ElementId>> list = new List<List<ElementId>>();
			return this.GetCellsEdgeLoops(poleList, ref list, bMergeEdge);
		}

		public List<List<Curve>> GetCellsEdgeLoops(List<Pole2D> poleList, ref List<List<ElementId>> edgeLoopsElementIds, bool bMergeEdge = true)
		{
			List<List<Curve>> list = new List<List<Curve>>();
			List<List<Curve>> result;
			try
			{
				if (poleList.Count == 0)
				{
					result = list;
				}
				else
				{
					List<Pole2D> poleList2 = this.SegmentPoleList(poleList);
					List<Pole2D> poleList3 = this.FilterOverlapPoleList(poleList2);
					List<Node2D> theNodes = new List<Node2D>();
					this.InitData(poleList3, Node2D.SearchType._Clockwise, ref theNodes);
					if (bMergeEdge)
					{
						this.MergeEdge(ref theNodes);
					}
					this.RecursiveDeleteSingleNode(ref theNodes);
					List<List<Pole2D>> outPoleList = new List<List<Pole2D>>();
					if (!this.SearchCells(theNodes, ref outPoleList))
					{
						result = list;
					}
					else
					{
						List<List<Pole2D>> outPoleList2 = new List<List<Pole2D>>();
						this.FormatPoleLoops(outPoleList, ref outPoleList2);
						this.GetLoopCurves(outPoleList2, StructureLoopSearcher.SearchEdgeLocation.SEL_Center, ref edgeLoopsElementIds, ref list);
						result = list;
					}
				}
			}
			catch (Exception)
			{
				result = list;
			}
			return result;
		}

        public List<List<Curve>> GetCellsEdgeLoops(List<Pole2D> poleList, ref List<List<ElementId>> edgeLoopsElementIds, StructureLoopSearcher.SearchEdgeLocation locType, bool bMergeEdge = true)
		{
			List<List<Curve>> list = new List<List<Curve>>();
			List<List<Curve>> result;
			try
			{
				if (poleList.Count == 0)
				{
					result = list;
				}
				else
				{
					List<Pole2D> poleList2 = this.SegmentPoleList(poleList);
					List<Pole2D> poleList3 = this.FilterOverlapPoleList(poleList2);
					List<Node2D> theNodes = new List<Node2D>();
					this.InitData(poleList3, Node2D.SearchType._Clockwise, ref theNodes);
					this.MergeEdge(ref theNodes);
					this.RecursiveDeleteSingleNode(ref theNodes);
					List<List<Pole2D>> outPoleList = new List<List<Pole2D>>();
					if (!this.SearchCells(theNodes, ref outPoleList))
					{
						result = list;
					}
					else
					{
						List<List<Pole2D>> outPoleList2 = new List<List<Pole2D>>();
						this.FormatPoleLoops(outPoleList, ref outPoleList2);
						this.GetLoopCurves(outPoleList2, locType, ref edgeLoopsElementIds, ref list);
						result = list;
					}
				}
			}
			catch (Exception)
			{
				result = list;
			}
			return result;
		}

		public void FormatDoubleLine(ref List<Pole2D> poleList)
		{
			try
			{
				List<Node2D> list = new List<Node2D>();
				this.FormatContinuousPoles(ref poleList, ref list);
			}
			catch (Exception)
			{
			}
		}

		public List<List<Curve>> OffsetLoop(List<Curve> curveLoop, double offset)
		{
			List<List<Curve>> list = new List<List<Curve>>();
			if (Geometry.IsEqual(offset, 0.0))
			{
				list.Add(curveLoop);
				return list;
			}
			bool isOutward = true;
			if (Geometry.LessThan(offset, 0.0))
			{
				isOutward = false;
			}
			List<KeyValuePair<Curve, double>> list2 = new List<KeyValuePair<Curve, double>>();
			foreach (Curve key in curveLoop)
			{
				KeyValuePair<Curve, double> item = new KeyValuePair<Curve, double>(key, Math.Abs(offset));
				list2.Add(item);
			}
			return this.OffsetLoop(list2, isOutward, true);
		}

		public List<List<Curve>> OffsetLoop(List<KeyValuePair<Curve, double>> edgeLoop, bool isOutward, bool bMergeEdge = true)
		{
			List<List<Curve>> list = new List<List<Curve>>();
			List<Pole2D> list2 = new List<Pole2D>();
			foreach (KeyValuePair<Curve, double> keyValuePair in edgeLoop)
			{
				Pole2D item = Pole2D.TransformWallToStructure2DPole(keyValuePair.Key, ElementId.InvalidElementId, Math.Abs(keyValuePair.Value), Math.Abs(keyValuePair.Value));
				list2.Add(item);
			}
			List<List<ElementId>> list3 = new List<List<ElementId>>();
			if (!isOutward)
			{
				List<List<Curve>> fullFloorEdgeLoops = this.GetFullFloorEdgeLoops(list2, bMergeEdge, ref list3, StructureLoopSearcher.SearchEdgeLocation.SEL_Inside);
				if (fullFloorEdgeLoops.Count != 1)
				{
					return list;
				}
				List<Pole2D> list4 = new List<Pole2D>();
				foreach (KeyValuePair<Curve, double> keyValuePair2 in edgeLoop)
				{
					Pole2D item2 = Pole2D.TransformWallToStructure2DPole(keyValuePair2.Key, ElementId.InvalidElementId, 0.0, 0.0);
					list4.Add(item2);
				}
				List<List<Curve>> fullFloorEdgeLoops2 = this.GetFullFloorEdgeLoops(list4, bMergeEdge, ref list3, StructureLoopSearcher.SearchEdgeLocation.SEL_Center);
				if (fullFloorEdgeLoops2.Count != 1)
				{
					return list;
				}
				bool flag = Geometry.IsAntiClockwise(this.GetLoopVertexes(fullFloorEdgeLoops2[0]));
				List<Pole2D> list5 = new List<Pole2D>();
				foreach (Curve curve in fullFloorEdgeLoops[0])
				{
					Pole2D item3 = Pole2D.TransformWallToStructure2DPole(curve, ElementId.InvalidElementId, 0.0, 0.0);
					list5.Add(item3);
				}
				using (List<List<Curve>>.Enumerator enumerator3 = this.GetCellsEdgeLoops(list5, false).GetEnumerator())
				{
					while (enumerator3.MoveNext())
					{
						List<Curve> list6 = enumerator3.Current;
						List<Curve> loop = this.SortLoopByOldSequence(list6, fullFloorEdgeLoops[0]);
						bool flag2 = Geometry.IsAntiClockwise(this.GetLoopVertexes(loop));
						if (flag == flag2)
						{
							list.Add(list6);
						}
					}
					return list;
				}
			}
			List<List<Curve>> fullFloorEdgeLoops3 = this.GetFullFloorEdgeLoops(list2, bMergeEdge, ref list3, StructureLoopSearcher.SearchEdgeLocation.SEL_Outside);
			list.Add(fullFloorEdgeLoops3[0]);
			return list;
		}

		public void GetSplitCurveWithOutsetFloor(Dictionary<Pole2D, bool> inputDictionary, ref List<Curve> splitCurves)
		{
			try
			{
				new List<Pole2D>();
				foreach (KeyValuePair<Pole2D, bool> keyValuePair in inputDictionary)
				{
					Pole2D key = keyValuePair.Key;
					if (Geometry.IsEqual(key.NegativeHalfWidth, 0.0) && Geometry.IsEqual(key.PositiveHalfWidth, 0.0))
					{
						splitCurves.Add(key.CenterCurve());
					}
					else if (key.IsPositiveDirection)
					{
						if (key.CenterCurve() is Line || !keyValuePair.Value)
						{
							splitCurves.Add(key.PositiveCurve());
						}
						else
						{
							splitCurves.Add(key.NegativeCurve());
						}
					}
					else
					{
						splitCurves.Add(key.NegativeCurve());
					}
				}
			}
			catch (Exception)
			{
			}
		}

		public List<Curve> AddCurveToUseCurves(List<Curve> lstUseCurves)
		{
			List<Curve> list = new List<Curve>();
			List<XYZ> list2 = new List<XYZ>();
			new Dictionary<XYZ, double>();
			for (int i = 0; i < lstUseCurves.Count; i++)
			{
				if (lstUseCurves[i] != null)
				{
					XYZ endPoint = lstUseCurves[i].GetEndPoint(0);
					XYZ endPoint2 = lstUseCurves[i].GetEndPoint(1);
					list2.Add(new XYZ(endPoint.X, endPoint.Y, 0.0));
					list2.Add(new XYZ(endPoint2.X, endPoint2.Y, 0.0));
				}
			}
			list = this.FindLinkeCurves(list2);
			list = this.DeleteRepeatLines(list);
			lstUseCurves.AddRange(list);
			return lstUseCurves;
		}

		public List<Curve> DeleteRepeatLines(List<Curve> lines)
		{
			List<Curve> list = new List<Curve>();
			for (int i = 0; i < lines.Count; i++)
			{
				Curve curve = lines[i];
				for (int j = 0; j < lines.Count; j++)
				{
					if (i != j && this.sureEqule(lines[j] as Line, lines[i] as Line))
					{
						if (lines[j].Length < lines[i].Length)
						{
							lines.RemoveAt(j);
							j--;
						}
						else
						{
							lines.RemoveAt(i);
							if (i < j)
							{
								j--;
							}
						}
					}
				}
			}
			return lines;
		}

		private bool sureEqule(Line line1, Line line2)
		{
			return (line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(0)) < 1E-06 && line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(1)) < 1E-06) || (line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(1)) < 1E-06 && line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(0)) < 1E-06);
		}

		private List<Curve> FindLinkeCurves(List<XYZ> inputPoints)
		{
			List<Curve> list = new List<Curve>();
			for (int i = 0; i < inputPoints.Count; i++)
			{
				XYZ xyz = inputPoints[i];
				XYZ xyz2 = null;
				double num = double.MaxValue;
				for (int j = 0; j < inputPoints.Count; j++)
				{
					if (i != j)
					{
						XYZ xyz3 = inputPoints[j];
						if (xyz.DistanceTo(xyz3) < num)
						{
							xyz2 = xyz3;
							num = xyz.DistanceTo(xyz3);
						}
					}
				}
				if (xyz2 != null && !Geometry.Lessthan_Or_Equal(num, 0.0) && !Geometry.IsEqual(xyz, xyz2, 0.01))
				{
					list.Add(Line.CreateBound(xyz, xyz2));
				}
			}
			return list;
		}

		private bool GetFullFloorEdgeLoops(List<Pole2D> poleList, bool mergeEdge, StructureLoopSearcher.SearchEdgeLocation edgeLocation, ref List<List<ElementId>> edgeLoopsElementIds, ref List<List<Curve>> edgeLoops)
		{
			bool result;
			try
			{
				List<List<Pole2D>> outPoleList = new List<List<Pole2D>>();
				if (!this.GetFullFloorEdgeLoops(poleList, mergeEdge, edgeLocation, ref outPoleList))
				{
					result = false;
				}
				else
				{
					this.GetLoopCurves(outPoleList, edgeLocation, ref edgeLoopsElementIds, ref edgeLoops);
					result = true;
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				result = false;
			}
			return result;
		}

		public bool GetFullFloorEdgeLoops(List<Pole2D> poleList, ref List<List<Curve>> edgeLoops)
		{
			StructureLoopSearcher.SearchEdgeLocation searchEdgeLocation = StructureLoopSearcher.SearchEdgeLocation.SEL_Center;
			bool result;
			try
			{
				if (poleList.Count == 0)
				{
					result = false;
				}
				else
				{
					List<Node2D> theNodes = new List<Node2D>();
					this.InitData(poleList, Node2D.SearchType._Anticlockwise, ref theNodes);
					this.RecursiveDeleteSingleNode(ref theNodes);
					List<List<Pole2D>> outPoleList = new List<List<Pole2D>>();
					if (!this.SearchOuterBoundary(theNodes, ref outPoleList))
					{
						result = false;
					}
					else
					{
						List<List<Pole2D>> outPoleList2 = new List<List<Pole2D>>();
						this.FormatPoleLoops(outPoleList, ref outPoleList2);
						List<List<ElementId>> list = new List<List<ElementId>>();
						this.GetLoopCurves(outPoleList2, searchEdgeLocation, ref list, ref edgeLoops);
						result = true;
					}
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				result = false;
			}
			return result;
		}

		private bool GetFullFloorEdgeLoops(List<Pole2D> poleList, bool mergeEdge, StructureLoopSearcher.SearchEdgeLocation edgeLocation, ref List<List<Pole2D>> edgeLoops)
		{
			bool result;
			try
			{
				if (poleList.Count == 0)
				{
					result = false;
				}
				else
				{
					List<Pole2D> poleList2 = this.SegmentPoleList(poleList);
					List<Pole2D> poleList3 = this.FilterOverlapPoleList(poleList2);
					List<Node2D> theNodes = new List<Node2D>();
					this.InitData(poleList3, Node2D.SearchType._Anticlockwise, ref theNodes);
					this.ShowPoleInfos("InitData", theNodes);
					if (mergeEdge)
					{
						this.MergeEdge(ref theNodes);
						this.ShowPoleInfos("MergeEdge", theNodes);
					}
					this.RecursiveDeleteSingleNode(ref theNodes);
					this.ShowPoleInfos("RecursiveDeleteSingleNode", theNodes);
					List<List<Pole2D>> outPoleList = new List<List<Pole2D>>();
					if (!this.SearchOuterBoundary(theNodes, ref outPoleList))
					{
						result = false;
					}
					else
					{
						this.FormatPoleLoops(outPoleList, ref edgeLoops);
						result = true;
					}
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				result = false;
			}
			return result;
		}

		private List<Curve> SortLoopByOldSequence(List<Curve> loop, List<Curve> oldLoop)
		{
			List<KeyValuePair<int, Curve>> list = new List<KeyValuePair<int, Curve>>();
			foreach (Curve curve in loop)
			{
				Curve value = curve;
				int i = 0;
				int num = -1;
				while (i < oldLoop.Count)
				{
					if (this.IsOverlapWithTowCurve(curve, oldLoop[i]))
					{
						num = i;
						break;
					}
					Curve curve2 = null;
					if (!this.IsSameNormal(curve, oldLoop[i], ref curve2))
					{
						value = curve2;
					}
					i++;
				}
				if (num != -1)
				{
					list.Add(new KeyValuePair<int, Curve>(num, value));
				}
			}
			list.Sort(new Comparison<KeyValuePair<int, Curve>>(StructureLoopSearcher.CurvePairCompare));
			List<Curve> list2 = new List<Curve>();
			foreach (KeyValuePair<int, Curve> keyValuePair in list)
			{
				list2.Add(keyValuePair.Value);
			}
			return list2;
		}

		internal static int CurvePairCompare(KeyValuePair<int, Curve> a, KeyValuePair<int, Curve> b)
		{
			if (a.Key < b.Key)
			{
				return -1;
			}
			if (a.Key > b.Key)
			{
				return 1;
			}
			return 0;
		}

		private bool IsOverlapWithTowCurve(Curve curve1, Curve curve2)
		{
			if (curve1.GetType() != curve2.GetType())
			{
				return false;
			}
			if (curve1.GetType() == typeof(Line))
			{
				XYZ xyz = null;
				XYZ xyz2 = null;
				Geometry.OverlapType overlapType = Geometry.IsOverlapOfTwoLine(curve1.GetEndPoint(0), curve1.GetEndPoint(1), curve2.GetEndPoint(0), curve2.GetEndPoint(1), ref xyz, ref xyz2, true, 1E-09, 1E-09);
				if (overlapType == Geometry.OverlapType._OT_Equality || overlapType == Geometry.OverlapType._OT_FirstIncludeSecond || overlapType == Geometry.OverlapType._OT_SecondIncludeFirst || overlapType == Geometry.OverlapType._OT_Part)
				{
					return true;
				}
			}
			else if (curve1.GetType() == typeof(Arc))
			{
				Arc arc = curve1 as Arc;
				Arc arc2 = curve2 as Arc;
				XYZ xyz3 = null;
				XYZ xyz4 = null;
				XYZ endPoint = arc.GetEndPoint(0);
				XYZ endPoint2 = arc.GetEndPoint(1);
				XYZ endPoint3 = arc2.GetEndPoint(0);
				XYZ endPoint4 = arc2.GetEndPoint(1);
				Geometry.OverlapType overlapType2 = Geometry.IsOverlapOfTwoArc(endPoint, endPoint2, arc.Center, arc.Normal, endPoint3, endPoint4, arc2.Center, arc2.Normal, ref xyz3, ref xyz4, 1E-09);
				if (overlapType2 == Geometry.OverlapType._OT_Equality || overlapType2 == Geometry.OverlapType._OT_FirstIncludeSecond || overlapType2 == Geometry.OverlapType._OT_SecondIncludeFirst || overlapType2 == Geometry.OverlapType._OT_Part)
				{
					return true;
				}
			}
			return false;
		}

		private bool IsSameNormal(Curve curve1, Curve curve2, ref Curve reverseCurve)
		{
			if (curve1.GetType() != curve2.GetType())
			{
				reverseCurve = curve1;
				return false;
			}
			if (curve1.GetType() == typeof(Line))
			{
				Line line = curve1 as Line;
				Line line2 = curve2 as Line;
				if (Geometry.IsEqual(line.Direction, line2.Direction))
				{
					return true;
				}
				reverseCurve = Line.CreateBound(curve1.GetEndPoint(1), curve1.GetEndPoint(0));
				return false;
			}
			else
			{
				if (!(curve1.GetType() == typeof(Arc)))
				{
					reverseCurve = curve1;
					return false;
				}
				Arc arc = curve1 as Arc;
				Arc arc2 = curve2 as Arc;
				if (Geometry.IsEqual(arc.Normal, arc2.Normal))
				{
					return true;
				}
				XYZ xyz = Geometry.CalculatMidPoint(arc);
				reverseCurve = Arc.Create(curve1.GetEndPoint(1), curve1.GetEndPoint(0), xyz);
				return false;
			}
		}

		private List<XYZ> GetLoopVertexes(List<Curve> loop)
		{
			List<XYZ> list = new List<XYZ>();
			foreach (Curve curve in loop)
			{
				list.Add(curve.GetEndPoint(0));
			}
			return list;
		}

		private void ShowPoleInfos(string step, List<Node2D> theNodes)
		{
		}

		private string ShowPoint(XYZ pt)
		{
			return string.Concat(new string[]
			{
				"X:",
				pt.X.ToString("F2"),
				" Y:",
				pt.Y.ToString("F2"),
				" Z:",
				pt.Z.ToString("F2")
			});
		}

		private List<Pole2D> SegmentPoleList(List<Pole2D> poleList)
		{
			List<Pole2D> list = new List<Pole2D>();
			List<List<XYZ>> list2 = new List<List<XYZ>>();
			List<Curve> list3 = new List<Curve>();
			foreach (Pole2D pole2D in poleList)
			{
				list2.Add(new List<XYZ>
				{
					pole2D.StartPoint,
					pole2D.EndPoint
				});
				XYZ xyz = pole2D.ExtendStartPoint(XYZComparer._eps);
				XYZ xyz2 = pole2D.ExtendEndPoint(XYZComparer._eps);
				try
				{
					Curve item;
					if (pole2D.IsArcPole)
					{
						XYZ xyz3 = XYZ.BasisZ;
						if (Geometry.LessThan(pole2D.Bulge, 0.0))
						{
							xyz3 = -xyz3;
						}
						XYZ center = pole2D.Center;
						XYZ xyz4 = Geometry.CalculatMidPoint(xyz, xyz2, center, xyz3);
						item = Arc.Create(xyz, xyz2, xyz4);
					}
					else
					{
						item = Line.CreateBound(xyz, xyz2);
					}
					list3.Add(item);
				}
				catch (Exception)
				{
				}
			}
			for (int i = 0; i < list3.Count; i++)
			{
				Curve curve = list3[i];
				for (int j = i + 1; j < list3.Count; j++)
				{
					Curve curve2 = list3[j];
					try
					{
						IntersectionResultArray intersectionResultArray;
						SetComparisonResult setComparisonResult = curve.Intersect(curve2, out intersectionResultArray);
						if (setComparisonResult == SetComparisonResult.Overlap || setComparisonResult == SetComparisonResult.Subset || setComparisonResult == SetComparisonResult.Superset)
						{
							foreach (object obj in intersectionResultArray)
							{
								IntersectionResult intersectionResult = (IntersectionResult)obj;
								if (intersectionResult.XYZPoint != null)
								{
									list2[i].Add(intersectionResult.XYZPoint);
									list2[j].Add(intersectionResult.XYZPoint);
								}
							}
						}
					}
					catch (Exception)
					{
					}
				}
			}
			for (int i = 0; i < poleList.Count; i++)
			{
				try
				{
					Pole2D pole2D2 = poleList[i];
					Curve curve3 = list3[i];
					List<XYZ> intersectPoints = list2[i];
					List<XYZ> list4 = Common.UniqueAndSortIntersectPoints(curve3, intersectPoints);
					if (list4.Count >= 2)
					{
						if (list4.Count == 2)
						{
							list.Add(pole2D2);
						}
						else
						{
							double positiveHalfWidth = pole2D2.PositiveHalfWidth;
							double negativeHalfWidth = pole2D2.NegativeHalfWidth;
							XYZ center2 = pole2D2.Center;
							for (int k = 0; k < list4.Count - 1; k++)
							{
								XYZ xyz5 = list4[k];
								XYZ xyz6 = list4[k + 1];
								if (!Geometry.LessThan(xyz5.DistanceTo(xyz6), XYZComparer._eps))
								{
									try
									{
										if (pole2D2.IsArcPole)
										{
											Pole2D item2 = Pole2D.NewStructure2DPole(pole2D2.ComponentId, xyz5, xyz6, center2, XYZ.BasisZ, positiveHalfWidth, negativeHalfWidth);
											list.Add(item2);
										}
										else
										{
											Pole2D item3 = Pole2D.NewStructure2DPole(pole2D2.ComponentId, xyz5, xyz6, positiveHalfWidth, negativeHalfWidth);
											list.Add(item3);
										}
									}
									catch (Exception)
									{
									}
								}
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
			return list;
		}

		private void MergeEdge(ref List<Node2D> theNodes)
		{
			try
			{
				Node2D leftBottomNode = this.GetLeftBottomNode(theNodes);
				for (int i = 0; i < theNodes.Count; i++)
				{
					Node2D node2D = theNodes[i];
					if (node2D.PoleList.Count == 2 && !Geometry.IsEqual(leftBottomNode.Position, node2D.Position))
					{
						Pole2D newPole = null;
						if (Pole2D.MergeTwoPole(node2D.PoleList[0], node2D.PoleList[1], ref newPole))
						{
							try
							{
								this.UpdateLinkedPole(node2D, node2D.PoleList[0], theNodes, newPole);
								this.UpdateLinkedPole(node2D, node2D.PoleList[1], theNodes, newPole);
								theNodes.RemoveAt(i);
								i--;
							}
							catch (Exception ex)
							{
								ex.ToString();
								i--;
							}
						}
					}
				}
			}
			catch (Exception ex2)
			{
				ex2.ToString();
			}
		}

		private void UpdateLinkedPole(Node2D curNode, Pole2D curPole, List<Node2D> theNodes, Pole2D newPole)
		{
			XYZ pos = curPole.CurEndPoint(curNode.Position);
			Node2D node2D = this.FindNodeByPos(theNodes, pos);
			if (node2D == null)
			{
				return;
			}
			int num = node2D.FindLinkPoleWithOtherNode(curNode.Position, Node2D.SearchType._Anticlockwise);
			if (-1 != num)
			{
				node2D.PoleList[num] = newPole;
			}
		}

		private void GetOtherCurves(List<List<Pole2D>> externalEdgeList, List<Pole2D> inputPoleList, ref List<Curve> interiorCurves)
		{
			List<ElementId> list = new List<ElementId>();
			foreach (List<Pole2D> list2 in externalEdgeList)
			{
				foreach (Pole2D pole2D in list2)
				{
					list.Add(pole2D.ComponentId);
				}
			}
			List<Pole2D> list3 = new List<Pole2D>();
			using (List<Pole2D>.Enumerator enumerator2 = inputPoleList.GetEnumerator())
			{
				while (enumerator2.MoveNext())
				{
					Pole2D inputPole = enumerator2.Current;
					if (list.FindIndex((ElementId s) => s.IntegerValue == inputPole.ComponentId.IntegerValue) < 0)
					{
						list3.Add(inputPole);
					}
				}
			}
			this.GetLoopCurves(list3, StructureLoopSearcher.SearchEdgeLocation.SEL_Center, ref interiorCurves, false);
		}

		private void GetInternalCurves(List<List<Pole2D>> externalEdgeList, List<Pole2D> inputPoleList, List<List<Curve>> edgeLoops, ref List<Curve> internalCurves)
		{
			List<Curve> list = new List<Curve>();
			this.GetOtherCurves(externalEdgeList, inputPoleList, ref list);
			List<List<XYZ>> list2 = new List<List<XYZ>>();
			foreach (List<Curve> list3 in edgeLoops)
			{
				List<XYZ> list4 = new List<XYZ>();
				foreach (Curve curve in list3)
				{
					list4.AddRange(curve.Tessellate());
				}
				list2.Add(list4);
			}
			new List<Curve>();
			foreach (Curve curve2 in list)
			{
				XYZ pt;
				if (curve2.GetType() == typeof(Line))
				{
					pt = Geometry.CalculatMidPoint(curve2 as Line);
				}
				else
				{
					if (!(curve2.GetType() == typeof(Arc)))
					{
						continue;
					}
					pt = Geometry.CalculatMidPoint(curve2 as Arc);
				}
				using (List<List<XYZ>>.Enumerator enumerator3 = list2.GetEnumerator())
				{
					while (enumerator3.MoveNext())
					{
						if (Geometry.PointInPloygon(enumerator3.Current, pt) == 1)
						{
							internalCurves.Add(curve2);
						}
					}
				}
			}
		}

		private List<Pole2D> FilterOverlapPoleList(List<Pole2D> poleList)
		{
			List<Pole2D> list = new List<Pole2D>();
			list.AddRange(poleList);
			for (int i = 0; i < list.Count; i++)
			{
				for (int j = i + 1; j < list.Count; j++)
				{
					Geometry.OverlapType overlapType = list[i].TestOverlap(list[j]);
					if (overlapType == Geometry.OverlapType._OT_Equality || overlapType == Geometry.OverlapType._OT_FirstIncludeSecond)
					{
						list.RemoveAt(j);
						j--;
					}
					else if (overlapType == Geometry.OverlapType._OT_SecondIncludeFirst)
					{
						list.RemoveAt(i);
						i--;
						break;
					}
				}
			}
			return list;
		}

		private void InitData(List<Pole2D> poleList, Node2D.SearchType searchType, ref List<Node2D> theNodes)
		{
			XYZEqualityComparer xyzequalityComparer = new XYZEqualityComparer();
			xyzequalityComparer.SetPrecision(3u);
			Dictionary<XYZ, Node2D> dictionary = new Dictionary<XYZ, Node2D>(xyzequalityComparer);
			foreach (Pole2D pole2D in poleList)
			{
				XYZ xyz = pole2D.StartPoint;
				if (!dictionary.ContainsKey(xyz))
				{
					Node2D value = new Node2D(xyz, new List<Pole2D>
					{
						pole2D
					});
					dictionary.Add(xyz, value);
				}
				else
				{
					dictionary[xyz].AddPole(pole2D);
				}
				xyz = pole2D.EndPoint;
				if (!dictionary.ContainsKey(xyz))
				{
					Node2D value2 = new Node2D(xyz, new List<Pole2D>
					{
						pole2D
					});
					dictionary.Add(xyz, value2);
				}
				else
				{
					dictionary[xyz].AddPole(pole2D);
				}
			}
			foreach (KeyValuePair<XYZ, Node2D> keyValuePair in dictionary)
			{
				if (searchType == Node2D.SearchType._Anticlockwise)
				{
					keyValuePair.Value.AnticlockwiseSortElements();
				}
				else
				{
					keyValuePair.Value.ClockwiseSortElements();
				}
				theNodes.Add(keyValuePair.Value);
			}
		}

		private void TrimAllNode(ref List<Node2D> theNodes)
		{
			foreach (Node2D node2D in theNodes)
			{
				int count = node2D.PoleList.Count;
				if (count != 1)
				{
					node2D.AnticlockwiseSortElements();
					List<Pole2D> poleList = node2D.PoleList;
					for (int i = 0; i < count; i++)
					{
						int index = i;
						int index2 = i + 1;
						if (i == count - 1)
						{
							index2 = 0;
						}
						Pole2D pole2D = poleList[index];
						Pole2D pole2D2 = poleList[index2];
						double dSAngle = 0.0;
						double dEAngle = 0.0;
						pole2D.GetAngle(node2D.Position, ref dSAngle);
						pole2D2.GetAngle(node2D.Position, ref dEAngle);
						if (!Geometry.IsEqual(Geometry.BetweenTheAngles(dSAngle, dEAngle, true), Math.PI))
						{
							this.TrimPoleSideline(node2D.Position, ref pole2D, ref pole2D2);
						}
					}
				}
			}
		}

		private void TrimPoleSideline(XYZ position, ref Pole2D pole1, ref Pole2D pole2)
		{
			try
			{
				XYZ xyz = pole1.CurNegativeStartPoint(position);
				XYZ xyz2 = pole1.CurNegativeEndPoint(position);
				if (xyz != null && xyz2 != null)
				{
					if (!Geometry.IsEqual(xyz, xyz2))
					{
						Curve curve;
						if (pole1.IsArcPole)
						{
							XYZ center = pole1.Center;
							XYZ xyz3 = Geometry.CalculatMidPoint(xyz, xyz2, center, XYZ.BasisZ);
							curve = Arc.Create(xyz, xyz2, xyz3);
						}
						else
						{
							curve = Line.CreateBound(xyz, xyz2);
						}
						XYZ xyz4 = pole2.CurPositiveStartPoint(position);
						XYZ xyz5 = pole2.CurPositiveEndPoint(position);
						if (xyz4 != null && xyz5 != null)
						{
							if (!Geometry.IsEqual(xyz4, xyz5))
							{
								Curve curve2;
								if (pole2.IsArcPole)
								{
									XYZ center2 = pole2.Center;
									XYZ xyz6 = Geometry.CalculatMidPoint(xyz4, xyz5, center2, XYZ.BasisZ);
									curve2 = Arc.Create(xyz4, xyz5, xyz6);
								}
								else
								{
									curve2 = Line.CreateBound(xyz4, xyz5);
								}
								XYZ xyz7 = Geometry.IntersectWithTwoCurves(curve, curve2, position, true, true, null);
								if (xyz7 != null)
								{
									pole1.SetCurNegativeStartPoint(position, xyz7);
									pole2.SetCurPositiveStartPoint(position, xyz7);
								}
							}
						}
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private bool SearchOuterBoundary(List<Node2D> theNodes, ref List<List<Pole2D>> outPoleList)
		{
			int num = -1;
			int num2 = 0;
			int num3 = 0;
			int num4 = theNodes.Count * 4;
			bool isFirstPt = true;
			List<XYZ> list = new List<XYZ>();
			List<double> list2 = new List<double>();
			List<Pole2D> list3 = new List<Pole2D>();
			Node2D node2D = null;
			Node2D prevNode = null;
			while (theNodes.Count > 1 && num2 < 2 && num3 < num4)
			{
				if (num == -1 || num == 1)
				{
					list = new List<XYZ>();
					list2 = new List<double>();
					list3 = new List<Pole2D>();
					Node2D leftBottomNode = this.GetLeftBottomNode(theNodes);
					if (leftBottomNode == null)
					{
						return false;
					}
					node2D = leftBottomNode;
					list.Add(node2D.Position);
					num3++;
					prevNode = null;
					isFirstPt = true;
				}
				Pole2D pole2D = null;
				Node2D nextNode = this.GetNextNode(isFirstPt, prevNode, node2D, theNodes, Node2D.SearchType._Anticlockwise, ref pole2D);
				if (nextNode != null)
				{
					double item = pole2D.CurBulge(node2D.Position);
					list2.Add(item);
					list3.Add(pole2D);
					prevNode = node2D;
					isFirstPt = false;
					node2D = nextNode;
					list.Add(node2D.Position);
					num3++;
					if (this.IsClosed(list))
					{
						double item2 = pole2D.CurBulge(node2D.Position);
						list2.Add(item2);
						if (list.Count > 1)
						{
							outPoleList.Add(list3);
						}
						this.DeleteNodeInClosedSpace(ref theNodes, list, list2);
						num = 1;
					}
					else
					{
						num = 0;
					}
					num2 = 0;
				}
				else
				{
					prevNode = null;
					isFirstPt = true;
					num2++;
					if (num2 == 2 && list.Count > 1)
					{
						outPoleList.Add(list3);
					}
				}
			}
			return true;
		}

		private void ShowNodeNumber(List<Pole2D> poleList)
		{
		}

		private bool SearchCells(List<Node2D> theNodes, ref List<List<Pole2D>> outPoleList)
		{
			int num = -1;
			int num2 = 0;
			int num3 = 0;
			int num4 = theNodes.Count * 4;
			bool isFirstPt = true;
			List<XYZ> list = new List<XYZ>();
			List<double> list2 = new List<double>();
			List<Pole2D> list3 = null;
			Node2D node2D = null;
			Node2D prevNode = null;
			while (theNodes.Count > 1 && num2 < 2 && num3 < num4)
			{
				if (num == -1 || num == 1)
				{
					list = new List<XYZ>();
					list2 = new List<double>();
					list3 = new List<Pole2D>();
					Node2D leftBottomNode = this.GetLeftBottomNode(theNodes);
					if (leftBottomNode == null)
					{
						return false;
					}
					node2D = leftBottomNode;
					list.Add(node2D.Position);
					num3++;
					prevNode = null;
					isFirstPt = true;
				}
				Pole2D nextEdge = null;
				Node2D nextNode = this.GetNextNode(isFirstPt, prevNode, node2D, theNodes, Node2D.SearchType._Clockwise, ref nextEdge);
				if (nextNode != null)
				{
					if (list3.FindIndex((Pole2D value) => value.SameAs(nextEdge)) == -1)
					{
						double item = nextEdge.CurBulge(node2D.Position);
						list2.Add(item);
						list3.Add(new Pole2D(nextEdge));
					}
					prevNode = node2D;
					isFirstPt = false;
					node2D = nextNode;
					list.Add(node2D.Position);
					num3++;
					if (this.IsClosed(list))
					{
						double item2 = nextEdge.CurBulge(node2D.Position);
						list2.Add(item2);
						if (list.Count > 1)
						{
							outPoleList.Add(list3);
						}
						this.DeletePassNode(ref theNodes, list);
						this.RecursiveDeleteSingleNode(ref theNodes);
						num = 1;
					}
					else
					{
						num = 0;
					}
					num2 = 0;
				}
				else
				{
					prevNode = null;
					isFirstPt = true;
					num2++;
					if (num2 == 2 && list.Count > 1)
					{
						outPoleList.Add(list3);
					}
				}
			}
			return true;
		}

		private Node2D GetLeftBottomNode(List<Node2D> theNodes)
		{
			XYZ xyz = theNodes[0].Position;
			Node2D result = null;
			foreach (Node2D node2D in theNodes)
			{
				XYZ position = node2D.Position;
				if (Geometry.IsEqual(position.DistanceTo(xyz), 0.0, 0.0001))
				{
					result = node2D;
				}
				else if (this.CompareXYLess(position, xyz, 0.0001))
				{
					xyz = position;
					result = node2D;
				}
			}
			return result;
		}

		private bool CompareXYLess(XYZ lhv, XYZ rhv, double eps)
		{
			if (Geometry.IsEqual(lhv.Y, rhv.Y, eps))
			{
				if (Geometry.LessThan(lhv.X, rhv.X, eps))
				{
					return true;
				}
			}
			else if (Geometry.LessThan(lhv.Y, rhv.Y, eps))
			{
				return true;
			}
			return false;
		}

		private Node2D GetNextNode(bool isFirstPt, Node2D PrevNode, Node2D CurNode, List<Node2D> theNodes, Node2D.SearchType searchType, ref Pole2D nextEdge)
		{
			Node2D result = null;
			if (isFirstPt)
			{
				List<Pole2D> poleList = CurNode.PoleList;
				double referenceStartAngle = 3.1416926535897933;
				poleList.Sort(new AngleComparerByNode(CurNode.Position, referenceStartAngle));
				int i = 0;
				int num = 0;
				while (i < poleList.Count)
				{
					Pole2D pole2D = poleList[i];
					double val = 0.0;
					pole2D.GetWinding(CurNode.Position, ref val);
					if (!Geometry.LessThan(val, 0.0))
					{
						break;
					}
					double val2 = 0.0;
					pole2D.GetAngle(CurNode.Position, ref val2);
					if (!Geometry.GreaterThan(val2, Math.PI) || !Geometry.Lessthan_Or_Equal(val2, 4.71238898038469))
					{
						break;
					}
					num++;
					i++;
				}
				int num2 = 0;
				if (num > 0)
				{
					num2 += num;
					if (num == poleList.Count)
					{
						num2--;
					}
				}
				nextEdge = poleList[num2];
				nextEdge.SetIsPositiveDirection(CurNode.Position);
				XYZ pos = nextEdge.CurEndPoint(CurNode.Position);
				result = this.FindNodeByPos(theNodes, pos);
			}
			else
			{
				int num3 = CurNode.FindLinkPoleWithOtherNode(PrevNode.Position, searchType);
				if (num3 != -1)
				{
					num3++;
					if (num3 == CurNode.PoleList.Count)
					{
						num3 = 0;
					}
					nextEdge = CurNode.PoleList[num3];
					nextEdge.SetIsPositiveDirection(CurNode.Position);
					XYZ pos2 = nextEdge.CurEndPoint(CurNode.Position);
					result = this.FindNodeByPos(theNodes, pos2);
				}
			}
			return result;
		}

		private Node2D FindNodeByPos(List<Node2D> theNodes, XYZ pos)
		{
			foreach (Node2D node2D in theNodes)
			{
				if (Geometry.IsEqual(pos.DistanceTo(node2D.Position), 0.0, XYZComparer._eps))
				{
					return node2D;
				}
			}
			return null;
		}

		private bool IsClosed(List<XYZ> BorderPos)
		{
			if (BorderPos.Count < 2)
			{
				return false;
			}
			XYZ xyz = BorderPos[0];
			XYZ xyz2 = BorderPos[BorderPos.Count - 1];
			return Geometry.IsEqual(xyz.DistanceTo(xyz2), 0.0, 0.0001);
		}

		private void DeleteNodeInClosedSpace(ref List<Node2D> theNodes, List<XYZ> points, List<double> bulges)
		{
			try
			{
				List<List<XYZ>> list = new List<List<XYZ>>();
				List<List<double>> list2 = new List<List<double>>();
				List<EdgeInfo> list3 = new List<EdgeInfo>();
				Geometry.ConvertToSimpleClosedPolylineAndSimpleCurve(points, bulges, ref list, ref list2, ref list3);
				List<List<XYZ>> list4 = new List<List<XYZ>>();
				for (int i = 0; i < list.Count; i++)
				{
					List<XYZ> item = new List<XYZ>();
					if (Geometry.GetFittingPolyline(list[i], list2[i], ref item, Common.MMToFeet(200.0)))
					{
						list4.Add(item);
					}
				}
				List<int> list5 = new List<int>();
				List<UV> list6 = new List<UV>();
				for (int i = 0; i < theNodes.Count; i++)
				{
					XYZ position = theNodes[i].Position;
					bool flag = false;
					for (int j = 0; j < list3.Count; j++)
					{
						EdgeInfo edgeInfo = list3[j];
						if (!Geometry.IsEqual(edgeInfo.StartPoint.DistanceTo(edgeInfo.EndPoint), 0.0, XYZComparer._eps))
						{
							if (edgeInfo.IsArc)
							{
								XYZ ptCenterOfArc = null;
								Geometry.GetCenterWithBulge(edgeInfo.StartPoint, edgeInfo.EndPoint, edgeInfo.Bulge, ref ptCenterOfArc);
								if (Geometry.Is_Point_OnSegment(edgeInfo.StartPoint, edgeInfo.EndPoint, ptCenterOfArc, XYZ.BasisZ, position, 1E-09))
								{
									list5.Add(i);
									list6.Add(new UV(position.X, position.Y));
									flag = true;
									break;
								}
							}
							else if (Geometry.Is_Point_OnSegment(edgeInfo.StartPoint, edgeInfo.EndPoint, position, 1E-09))
							{
								list5.Add(i);
								list6.Add(new UV(position.X, position.Y));
								flag = true;
								break;
							}
						}
					}
					if (!flag)
					{
						for (int j = 0; j < list4.Count; j++)
						{
							if (Geometry.PointInPloygon(list4[j], position) != -1)
							{
								list5.Add(i);
								list6.Add(new UV(position.X, position.Y));
								break;
							}
						}
					}
				}
				List<int> list7 = new List<int>();
				for (int i = 0; i < list6.Count; i++)
				{
					int num = list5[i];
					Node2D node2D = theNodes[num];
					List<Pole2D> poleList = node2D.PoleList;
					XYZ position2 = node2D.Position;
					int k = 0;
					while (k < poleList.Count)
					{
						XYZ xyz = poleList[k].CurEndPoint(position2);
						if (xyz == null)
						{
							k++;
						}
						else
						{
							UV pt2d = new UV(xyz.X, xyz.Y);
							int num2 = list6.FindIndex((UV s) => Geometry.IsEqual(s.DistanceTo(pt2d), 0.0, XYZComparer._eps));
							if (num2 == -1)
							{
								k++;
							}
							else
							{
								Node2D node2D2 = this.FindNodeByPos(theNodes, xyz);
								if (node2D2 == null)
								{
									k++;
								}
								else
								{
									poleList.RemoveAt(k);
									num2 = node2D2.FindLinkPoleWithOtherNode(position2, Node2D.SearchType._Clockwise);
									if (num2 != -1)
									{
										node2D2.RemoveEdge(num2);
									}
								}
							}
						}
					}
					if (poleList.Count == 0)
					{
						list7.Add(num);
					}
					else
					{
						node2D.AnticlockwiseSortElements();
					}
				}
				for (int i = list7.Count - 1; i >= 0; i--)
				{
					theNodes.RemoveAt(list7[i]);
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
				theNodes.Clear();
			}
		}

		private void FormatPoleLoops(List<List<Pole2D>> outPoleList, ref List<List<Pole2D>> formatPoleLoops)
		{
			for (int i = 0; i < outPoleList.Count; i++)
			{
				List<Pole2D> list = outPoleList[i];
				for (int j = 0; j < list.Count - 1; j++)
				{
					Pole2D pole = list[j];
					int num = list.FindIndex(j + 1, (Pole2D s) => s == pole);
					if (num >= 0 && num != j)
					{
						List<Pole2D> range = list.GetRange(0, j);
						List<Pole2D> range2 = list.GetRange(j + 1, num - j - 1);
						List<Pole2D> collection = new List<Pole2D>();
						if (num < list.Count - 1)
						{
							collection = list.GetRange(num + 1, list.Count - (num + 1));
						}
						range.AddRange(collection);
						if (range.Count > 1)
						{
							outPoleList.Add(range);
						}
						if (range2.Count > 1)
						{
							outPoleList.Add(range2);
						}
						outPoleList.RemoveAt(i);
						i--;
						break;
					}
				}
			}
			List<Pole2D> list2 = new List<Pole2D>();
			foreach (List<Pole2D> list3 in outPoleList)
			{
				formatPoleLoops.Add(list3);
				list2.AddRange(list3);
			}
			List<Node2D> list4 = new List<Node2D>();
			this.FormatContinuousPoles(ref list2, ref list4);
		}

		private void FormatContinuousPoles(ref List<Pole2D> continuousPoles, ref List<Node2D> theNodes)
		{
			List<Pole2D> poleList = this.SegmentPoleList(continuousPoles);
			List<Pole2D> poleList2 = this.FilterOverlapPoleList(poleList);
			this.InitData(poleList2, Node2D.SearchType._Anticlockwise, ref theNodes);
			this.TrimAllNode(ref theNodes);
			continuousPoles.Clear();
			foreach (Node2D node2D in theNodes)
			{
				using (List<Pole2D>.Enumerator enumerator2 = node2D.PoleList.GetEnumerator())
				{
					while (enumerator2.MoveNext())
					{
						Pole2D pole = enumerator2.Current;
						if (continuousPoles.FindIndex((Pole2D s) => s.SameAs(pole)) == -1)
						{
							continuousPoles.Add(pole);
						}
					}
				}
			}
		}

		private void GetLoopCurves(List<List<Pole2D>> outPoleList, StructureLoopSearcher.SearchEdgeLocation searchEdgeLocation, ref List<List<Curve>> edgeLoops, bool bIsNeedAddCurve)
		{
			foreach (List<Pole2D> loop in outPoleList)
			{
				List<Curve> item = new List<Curve>();
				this.GetLoopCurves(loop, searchEdgeLocation, ref item, bIsNeedAddCurve);
				edgeLoops.Add(item);
			}
		}

		private void GetLoopCurves(List<List<Pole2D>> outPoleList, StructureLoopSearcher.SearchEdgeLocation searchEdgeLocation, ref List<List<ElementId>> edgeLoopsElementIds, ref List<List<Curve>> edgeLoops)
		{
			foreach (List<Pole2D> loop in outPoleList)
			{
				List<Curve> item = new List<Curve>();
				List<ElementId> item2 = new List<ElementId>();
				this.GetLoopCurves(loop, searchEdgeLocation, ref item2, ref item, true);
				edgeLoopsElementIds.Add(item2);
				edgeLoops.Add(item);
			}
		}

		private void GetLoopCurves(List<Pole2D> loop, StructureLoopSearcher.SearchEdgeLocation searchEdgeLocation, ref List<Curve> edgeLoop, bool bIsNeedAddCurve)
		{
			List<ElementId> list = new List<ElementId>();
			this.GetLoopCurves(loop, searchEdgeLocation, ref list, ref edgeLoop, bIsNeedAddCurve);
		}

		private void GetLoopCurves(List<Pole2D> loop, StructureLoopSearcher.SearchEdgeLocation searchEdgeLocation, ref List<ElementId> edgeLoopElementIds, ref List<Curve> edgeLoop, bool bIsNeedAddCurve = true)
		{
			if (loop.Count == 2 && loop[0].SameAs(loop[1]))
			{
				return;
			}
			XYZ xyz = null;
			foreach (Pole2D pole2D in loop)
			{
				XYZ xyz2 = null;
				XYZ xyz3 = null;
				XYZ xyz4 = XYZ.BasisZ;
				if (searchEdgeLocation == StructureLoopSearcher.SearchEdgeLocation.SEL_Center)
				{
					if (pole2D.IsPositiveDirection)
					{
						xyz2 = pole2D.StartPoint;
						xyz3 = pole2D.EndPoint;
					}
					else
					{
						xyz2 = pole2D.EndPoint;
						xyz3 = pole2D.StartPoint;
						xyz4 = -xyz4;
					}
				}
				else if (searchEdgeLocation == StructureLoopSearcher.SearchEdgeLocation.SEL_Outside)
				{
					if (pole2D.IsPositiveDirection)
					{
						xyz2 = pole2D.PositiveStartPoint;
						xyz3 = pole2D.PositiveEndPoint;
					}
					else
					{
						xyz2 = pole2D.NegativeEndPoint;
						xyz3 = pole2D.NegativeStartPoint;
						xyz4 = -xyz4;
					}
				}
				else if (pole2D.IsPositiveDirection)
				{
					xyz2 = pole2D.NegativeStartPoint;
					xyz3 = pole2D.NegativeEndPoint;
				}
				else
				{
					xyz2 = pole2D.PositiveEndPoint;
					xyz3 = pole2D.PositiveStartPoint;
					xyz4 = -xyz4;
				}
				if (bIsNeedAddCurve)
				{
					if (xyz != null && !Geometry.IsEqual(xyz, xyz2, 0.0001))
					{
						try
						{
							Curve item = YJKLineEx.YJKGetBound(xyz, xyz2);
							edgeLoopElementIds.Add(ElementId.InvalidElementId);
							edgeLoop.Add(item);
						}
						catch (Exception)
						{
							continue;
						}
					}
					xyz = xyz3;
				}
				Curve item2 = null;
				if (pole2D.IsArcPole)
				{
					XYZ center = pole2D.Center;
					XYZ xyz5 = Geometry.CalculatMidPoint(xyz2, xyz3, center, xyz4);
					try
					{
						if (Geometry.LessThan(pole2D.Bulge, 0.0))
						{
							item2 = Arc.Create(xyz3, xyz2, xyz5);
						}
						else
						{
							item2 = Arc.Create(xyz2, xyz3, xyz5);
						}
						goto IL_18C;
					}
					catch (Exception)
					{
						continue;
					}
				}
				try
				{
					item2 = YJKLineEx.YJKGetBound(xyz2, xyz3);
				}
				catch (Exception)
				{
					continue;
				}
				IL_18C:
				edgeLoopElementIds.Add(pole2D.ComponentId);
				edgeLoop.Add(item2);
			}
			if (bIsNeedAddCurve)
			{
				if (edgeLoop.Count == 0)
				{
					return;
				}
				XYZ endPoint = edgeLoop[0].GetEndPoint(0);
				XYZ endPoint2 = edgeLoop[edgeLoop.Count - 1].GetEndPoint(1);
				if (!Geometry.IsEqual(endPoint, endPoint2))
				{
					try
					{
						Curve item3 = YJKLineEx.YJKGetBound(endPoint2, endPoint);
						edgeLoopElementIds.Add(ElementId.InvalidElementId);
						edgeLoop.Add(item3);
					}
					catch (Exception)
					{
					}
				}
			}
		}

		private void DeleteSingleSideLineByBound(XYZ passInPos, XYZ passOutPos, ref List<Node2D> CurNodeAry)
		{
			for (int i = 0; i < CurNodeAry.Count; i++)
			{
				Node2D node2D = CurNodeAry[i];
				for (int j = 0; j < node2D.PoleList.Count; j++)
				{
					Pole2D pole2D = node2D.PoleList[j];
					XYZ startPoint = pole2D.StartPoint;
					XYZ endPoint = pole2D.EndPoint;
					if ((Geometry.IsEqual(passInPos, startPoint) && Geometry.IsEqual(passOutPos, endPoint)) || (Geometry.IsEqual(passInPos, endPoint) && Geometry.IsEqual(passOutPos, startPoint)))
					{
						CurNodeAry[i].PoleList.RemoveAt(j);
					}
				}
			}
		}

		private void DeleteNodeByBound(int nodeIndex, ref List<Node2D> CurNodeAry)
		{
			List<KeyValuePair<XYZ, XYZ>> list = new List<KeyValuePair<XYZ, XYZ>>();
			for (int i = 0; i < CurNodeAry[nodeIndex].PoleList.Count; i++)
			{
				Pole2D pole2D = CurNodeAry[nodeIndex].PoleList[i];
				KeyValuePair<XYZ, XYZ> item = new KeyValuePair<XYZ, XYZ>(pole2D.StartPoint, pole2D.EndPoint);
				list.Add(item);
			}
			for (int i = 0; i < list.Count; i++)
			{
				XYZ key = list[i].Key;
				XYZ value = list[i].Value;
				this.DeleteSingleSideLineByBound(key, value, ref CurNodeAry);
			}
			CurNodeAry.RemoveAt(nodeIndex);
		}

		private void RecursiveDeleteSingleNode(ref List<Node2D> nodeInfos)
		{
			int num = 0;
			for (int i = 0; i < nodeInfos.Count; i++)
			{
				if (nodeInfos[i].PoleList.Count < 2)
				{
					this.DeleteNodeByBound(i, ref nodeInfos);
					i--;
					num++;
				}
			}
			if (num > 0)
			{
				this.RecursiveDeleteSingleNode(ref nodeInfos);
			}
		}

		private void DeletePassNode(ref List<Node2D> CurFloorNodeDate, List<XYZ> points)
		{
			List<int> list = new List<int>();
			List<int> list2 = new List<int>();
			for (int i = 0; i < points.Count - 1; i++)
			{
				XYZ xyz = points[i];
				for (int j = 0; j < CurFloorNodeDate.Count; j++)
				{
					XYZ position = CurFloorNodeDate[j].Position;
					if (xyz == position)
					{
						if (CurFloorNodeDate[j].PoleList.Count > 2)
						{
							list2.Add(j);
						}
						list.Add(j);
						break;
					}
				}
			}
			int count = list2.Count;
			if (count == 1)
			{
				int index = list2[0];
				int num = list.FindIndex((int value) => value == index);
				if (num != -1)
				{
					list.RemoveAt(num);
				}
			}
			else if (count >= 2)
			{
				int indexS = list2[0];
				int num2 = list.FindIndex((int value) => value == indexS);
				if (num2 != -1)
				{
					if (num2 == 0)
					{
						int indexE = list2[1];
						int num3 = list.FindIndex((int value) => value == indexE);
						if (num3 != -1)
						{
							if (num3 - num2 == 1)
							{
								XYZ position2 = CurFloorNodeDate[indexS].Position;
								XYZ position3 = CurFloorNodeDate[indexE].Position;
								this.DeleteSingleSideLineByBound(position2, position3, ref CurFloorNodeDate);
								this.DeleteSingleSideLineByBound(position3, position2, ref CurFloorNodeDate);
							}
							list.RemoveRange(num3, list.Count - num3);
							list.RemoveAt(num2);
						}
					}
					else
					{
						int indexE = list2[list2.Count - 1];
						int num4 = list.FindIndex((int value) => value == indexE);
						if (num4 != -1)
						{
							if (num4 == list.Count - 1)
							{
								list.RemoveRange(num2, num4 - num2 + 1);
							}
							else
							{
								list.RemoveRange(num2, num4 + 1 - num2 + 1);
							}
						}
					}
				}
			}
			if (list.Count != 0)
			{
				list.Sort();
				for (int i = list.Count - 1; i > -1; i--)
				{
					this.DeleteNodeByBound(list[i], ref CurFloorNodeDate);
				}
			}
		}

		private double m_OldEps = XYZComparer._eps;

		private Document m_Doc;

		private ExternalCommandData m_Revit;

		public enum SearchEdgeLocation
		{
			SEL_Inside,
			SEL_Center,
			SEL_Outside
		}
	}
}
